package com.wangxin.study8.threadtest;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author jojo.wang
 * @title: ReentrantLockQueueTest
 * @projectName study8
 * @description: TODO
 * @date 2019/5/715:51
 */

public class ReentrantLockQueueTest {
    /**
     * 可重入锁
     */
    private final ReentrantLock lock = new ReentrantLock();

    /**
     * 写线程条件
     */
    private final Condition notFull = lock.newCondition();

    /**
     * 读线程条件
     */
    private final Condition notEmpty = lock.newCondition();

    /**
     * 缓存队列数组
     */
    private Object[] items = new Object[10];

    private int count = 0;

    private int putPtr = 0;

    private int takePtr = 0;

    /**
     * 模拟队列写入方法
     * @param x
     * @throws InterruptedException
     */
    public void put(Object x) throws InterruptedException{
        lock.lock();
        System.out.println("put obj");
        try {
            while (count == items.length){
                System.out.println("阻塞写入线程");
                notFull.await();
            }
            items[putPtr] = x;
            //如果写索引写到队列的最后一个位置了，那么置为0
            if (++putPtr == items.length){
                putPtr=0;
            }
            ++count;
            //唤醒读线程
            notEmpty.signal();
        }finally {
            lock.unlock();
        }
    }

    public Object take() throws InterruptedException{
        System.out.println("take");
        lock.lock();
        try {
            while (count==0){
                System.out.println("阻塞读取线程");
                notEmpty.await();
            }
            Object x = items[takePtr];
            //如果读索引读到队列的最后一个位置了，那么置为0
            if (++takePtr == items.length){
                takePtr=0;
            }
            --count;
            notFull.signal();
            return x;
        }finally {
            lock.unlock();
        }
    }
}
